package face.pay.api.payter.channel.paytype.wechat;

import com.alibaba.fastjson.JSONObject;
import com.face.pay.WxApiConfig;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import face.pay.api.payter.channel.paytype.AbstractPayType;
import face.pay.api.payter.channel.paytype.wechat.api.ApiWxPayQuery;
import face.pay.api.wechat.param.PayParam;
import face.pay.config.SystemConfig;
import face.pay.constant.OrderType;
import face.pay.constant.PayType;
import face.pay.entity.EnterpriseInfo;
import face.pay.entity.OemInfo;
import face.pay.entity.OrderInfo;
import face.pay.entity.StoreInfo;
import face.pay.util.IpUtils;
import face.pay.util.MathUtil;
import face.pay.util.ResultMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 扫商家二维码
 * html js 支付
 */
@Component
@Slf4j
public class WxJsPay extends AbstractPayType {

    private static final String domain = "api.mch.weixin.qq.com";

    private static final String urlSuffix = "/pay/unifiedorder";

    @Autowired
    ApiWxPayQuery apiPayQuery;

    @Autowired
    private  SystemConfig systemConfig;

    @Override
    public ResultMessage pay(JSONObject json) {

        try {
            PayParam payParam = json.toJavaObject(PayParam.class);

            StoreInfo storeInfo = this.storeInfoDao.getById(payParam.getStoreId());

            EnterpriseInfo enterpriseInfo = this.enterpriseInfoDao.getById(storeInfo.getEnterpriseId());

            Integer oemId = enterpriseInfo.getOemId();
            OemInfo oemInfo = this.oemInfoDao.getOemInfoById(oemId);


          Integer sqlStatus = enterpriseInfo.getSqrStatus();
          if(new Integer(1).equals(sqlStatus)){

              Long sqrLimit = enterpriseInfo.getSqrLimit()==null?Long.valueOf(0):enterpriseInfo.getSqrLimit();


              if(sqrLimit.compareTo(Long.valueOf(0))==1){

                  if(payParam.getTotal_fee().compareTo(sqrLimit)==1){
                      return ResultMessage.createFail("收款超限最大支付金额为："+MathUtil.transForMoney(sqrLimit)+"/元");

                  }
              }


          }else {
              return ResultMessage.createFail("此功能已关闭，请用其他方式支付");
          }


            String safe = this.paySafe(payParam.getTerminalId(),payParam.getCardDetailId(), payParam.getTotal_fee(),payParam.getAct_fee());

            if (StringUtils.isNotBlank(safe)) {
                log.info("交易信息不正确，中断支付");
                return ResultMessage.createFail("交易信息不正确，中断支付");
            } else {
                WxApiConfig wxApiConfig = this.iWxPayConfigServer.getConfig(oemId);

                if (wxApiConfig.validate()) {

                    WXPayRequest wxPayRequest = new WXPayRequest(wxApiConfig);

                    String appId = wxApiConfig.getAppID();
                    String apiKey = wxApiConfig.getKey();
                    String mchId = wxApiConfig.getMchID();

                    String subMchId = enterpriseInfo.getWxSubMchId();

                    if (StringUtils.isBlank(subMchId)) {
                        log.info("商家商户号错误");
                        return ResultMessage.createFail("商家商户号错误");
                    }

                    String body = storeInfo.getName() + "-线下支付";
                    String ip = IpUtils.getIpAddress();

                    String notify_url = systemConfig.getWx_notify_url();

                    Map<String, String> dataMap = new HashMap<>();

                    OrderInfo orderInfo =  new OrderInfo();
                    orderInfo.setStoreId(payParam.getStoreId());
                    orderInfo.setUserId(enterpriseInfo.getUserId());
                    orderInfo.setOemId(oemId);
                    orderInfo.setType(OrderType.WECHAT);
                    orderInfo.setChannelCode(payParam.getChannelCode());
                    orderInfo.setPayType(PayType.QRCODE);
                    orderInfo.setScene(1);
                    orderInfo.setSubsidyMoney(new Long(0));
                    orderInfo.setTerminalId(payParam.getTerminalId());
                    orderInfo.setTotalFee(payParam.getTotal_fee());
                    orderInfo.setIp(payParam.getIp());
                    orderInfo.setStatus(0);

                    this.orderInfoDao.insert(orderInfo);


                    String out_trade_no = String.valueOf(orderInfo.getId());

                    if(payParam.getCardDetailId()!=null && payParam.getCardDetailId()>0){
                        dataMap.put("profit_sharing","Y");
                        orderInfo.setCardDetailId(payParam.getCardDetailId());
                    }

                    dataMap.put("appid", appId);
                    dataMap.put("mch_id", mchId);
                    dataMap.put("sub_mch_id", subMchId);
                    dataMap.put("nonce_str", WXPayUtil.generateNonceStr());
                    dataMap.put("body", body);
                    dataMap.put("out_trade_no", out_trade_no);
                    dataMap.put("total_fee", String.valueOf(payParam.getAct_fee()));
                    dataMap.put("spbill_create_ip", ip);
                    dataMap.put("notify_url", notify_url);
                    dataMap.put("trade_type", "JSAPI");
                    dataMap.put("openid", payParam.getOpenid());

                    String xml = WXPayUtil.generateSignedXml(dataMap, apiKey);
                    log.info("微信js支付" + xml);


                    String result = wxPayRequest.requestOnce(domain, urlSuffix, xml, false);
                    log.info("返回结果 " + result);

                    Map<String, String> resultMap = WXPayUtil.xmlToMap(result);

                    if (WXPayUtil.isSuccess(resultMap)) {

                        //准备前段js支付参数
                        String prepay_id =  resultMap.get("prepay_id");

                        Map<String, String> jsData = new HashMap<>();
                        jsData.put("appId", appId);
                        jsData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
                        jsData.put("nonceStr", WXPayUtil.generateNonceStr());
                        jsData.put("package", "prepay_id=" + prepay_id);
                        jsData.put("signType", "MD5");
                        String sign = WXPayUtil.generateSignature(jsData, apiKey);
                        jsData.put("paySign", sign);

                        orderInfo.setActFee(payParam.getAct_fee());
                        orderInfo.setActInnerFee(payParam.getAct_fee());
                        orderInfo.setPayCode(prepay_id);
                        orderInfo.setPayUserSign(payParam.getOpenid());

                        this.orderInfoDao.updatePayInfo(orderInfo);

                        apiPayQuery.orderStatusCheck(orderInfo.getId(),subMchId,wxApiConfig,oemInfo);

                        return ResultMessage.createSuccess(jsData);
                    } else {
                        log.info("微信jsapi支付接口调用失败  商家:{}");
                        return ResultMessage.createFail("支付失败!!!");
                    }

                } else {
                    log.info("服务商信息错误");
                    return ResultMessage.createFail("服务商信息错误");

                }
            }


        }catch (Exception e){
            log.info("微信JS异常",e);
            return  ResultMessage.createError("支付异常");
        }

    }

}
